{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(60000, 28, 28)\n"
     ]
    }
   ],
   "source": [
    "import tensorflow.keras as keras\n",
    "import pandas as pd\n",
    "import tensorflow.compat.v1 as tf\n",
    "tf.disable_v2_behavior()\n",
    "import numpy as np\n",
    "\n",
    "\n",
    "(x,y), (x_test,y_test) = keras.datasets.mnist.load_data()  #numpy中的格式\n",
    "print(x.shape)\n",
    "x = x.reshape(60000,784)\n",
    "y = pd.get_dummies(y).values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "## 超参数\n",
    "learning_rate = 0.001\n",
    "epoch = 100\n",
    "display_step = 10\n",
    "batch_size = 10000\n",
    "iteration = x.shape[0]/batch_size\n",
    "shuffle = False  #\n",
    "# 神经网络参数\n",
    "n_hidden_1 = 256 # 第一层神经元个数\n",
    "n_hidden_2 = 256 # 第二层神经元个数\n",
    "num_input = 784 # MNIST 输入数据(图像大小: 28*28)\n",
    "num_classes = 10 # MNIST 手写体数字类别 (0-9)\n",
    "\n",
    "# 输入到数据流图中的训练数据\n",
    "X = tf.placeholder(\"float\", [None, num_input],name = \"X\")\n",
    "Y = tf.placeholder(\"float\", [None, num_classes],name = \"Y\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# 权重和偏置\n",
    "weights = {\n",
    "    'h1': tf.Variable(tf.random_normal([num_input, n_hidden_1]),name=\"h1\"),\n",
    "    'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2]),name=\"h2\"),\n",
    "    'out': tf.Variable(tf.random_normal([n_hidden_2, num_classes]),name=\"outh\")\n",
    "}\n",
    "biases = {\n",
    "    'b1': tf.Variable(tf.random_normal([n_hidden_1]),name=\"b1\"),\n",
    "    'b2': tf.Variable(tf.random_normal([n_hidden_2]),name=\"b2\"),\n",
    "    'out': tf.Variable(tf.random_normal([num_classes]),name=\"outb\")\n",
    "}\n",
    "\n",
    "# 定义神经网络\n",
    "def neural_net(x):\n",
    "    # 第一层隐藏层（256个神经元）\n",
    "    layer_1 = (tf.add(tf.matmul(x, weights['h1']), biases['b1']))\n",
    "    # 第二层隐藏层（256个神经元）\n",
    "    layer_2 = tf.nn.relu(tf.add(tf.matmul(layer_1, weights['h2']), biases['b2']))\n",
    "    # 输出层\n",
    "    out_layer = (tf.add(tf.matmul(layer_2, weights['out']) , biases['out'],name = \"output\"))\n",
    "    return out_layer\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "404217.53\n",
      "Step 1, Minibatch Loss= 404217.5312, Training Accuracy= 0.176\n",
      "56999.035\n",
      "Step 10, Minibatch Loss= 56999.0352, Training Accuracy= 0.699\n",
      "31291.514\n",
      "Step 20, Minibatch Loss= 31291.5137, Training Accuracy= 0.806\n",
      "22461.041\n",
      "Step 30, Minibatch Loss= 22461.0410, Training Accuracy= 0.849\n",
      "17713.293\n",
      "Step 40, Minibatch Loss= 17713.2930, Training Accuracy= 0.873\n",
      "14627.04\n",
      "Step 50, Minibatch Loss= 14627.0400, Training Accuracy= 0.888\n",
      "12433.792\n",
      "Step 60, Minibatch Loss= 12433.7920, Training Accuracy= 0.900\n",
      "10778.886\n",
      "Step 70, Minibatch Loss= 10778.8857, Training Accuracy= 0.910\n",
      "9430.975\n",
      "Step 80, Minibatch Loss= 9430.9746, Training Accuracy= 0.918\n",
      "8297.221\n",
      "Step 90, Minibatch Loss= 8297.2207, Training Accuracy= 0.923\n",
      "7360.8096\n",
      "Step 100, Minibatch Loss= 7360.8096, Training Accuracy= 0.931\n",
      "Optimization Finished!\n"
     ]
    }
   ],
   "source": [
    "\n",
    "# 构建模型\n",
    "logits = neural_net(X)\n",
    "# 定义损失函数和优化器\n",
    "loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(\n",
    "    logits=logits, labels=Y))\n",
    "\n",
    "optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)\n",
    "train_op = optimizer.minimize(loss_op)\n",
    "# 定义预测准确率\n",
    "correct_pred = tf.equal(tf.argmax(logits, 1), tf.argmax(Y, 1))\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))\n",
    "# 初始化所有变量（赋默认值）\n",
    "init = tf.global_variables_initializer()\n",
    "\n",
    "# 开始训练\n",
    "with tf.Session() as sess:\n",
    "    # 执行初始化操作\n",
    "    sess.run(init)\n",
    "    for step in range(1, epoch + 1):\n",
    "        for batch_step in range(0,int(iteration)):\n",
    "            batch_x  =  x[batch_step*batch_size:(batch_step + 1)*batch_size,:]\n",
    "            batch_y =   y[batch_step*batch_size:(batch_step + 1)*batch_size,:]\n",
    "            \n",
    "            # 每批batch进行混淆\n",
    "            if shuffle == True:\n",
    "                ind_shuf = list(range(batch_size))\n",
    "                np.random.shuffle(ind_shuf)\n",
    "                batch_x = batch_x[ind_shuf,:]\n",
    "                batch_y = batch_y[ind_shuf,:]\n",
    "            # 每个batch执行训练操作，包括前向和后向运算\n",
    "            sess.run(train_op, feed_dict={X: batch_x, Y: batch_y})\n",
    "\n",
    "        if step % display_step == 0 or step == 1:\n",
    "            # 计算损失值和准确率\n",
    "            loss, acc = sess.run([loss_op, accuracy], feed_dict={X: batch_x,\n",
    "                                                                 Y: batch_y})\n",
    "            print(loss)\n",
    "            print(\"Step \" + str(step) + \", Minibatch Loss= \" + \\\n",
    "                  \"{:.4f}\".format(loss) + \", Training Accuracy= \" + \\\n",
    "                  \"{:.3f}\".format(acc))\n",
    "            \n",
    "    print(\"Optimization Finished!\")\n",
    "    saver = tf.train.Saver()\n",
    "    saver.save(sess, './model/mininst.ckpt')\n",
    "    tenboard_dir = './tensorboard/test1/'\n",
    "    # 指定一个文件用来保存图\n",
    "    writer = tf.summary.FileWriter(tenboard_dir + \"test\")\n",
    "    # 把图add进去\n",
    "    writer.add_graph(sess.graph)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  },
  "pycharm": {
   "stem_cell": {
    "cell_type": "raw",
    "metadata": {
     "collapsed": false
    },
    "source": [
     "# import tensorflow.compat.v1 as tf\n",
     "import tensorflow.keras as keras\n",
     "tf.disable_v2_behavior()\n",
     "\n",
     "(x,y), (x_test,y_test) = keras.datasets.mnist.load_data()  #numpy中的格式\n",
     "print(x.shape, y.shape)    #y为vector\n",
     "x1 = x[1,:,:]\n",
     "print(y[:4])\n",
     "y = tf.one_hot(y, depth=10)\n",
     "print(y[:4])\n",
     "print(x_test.shape,y_test.shape)\n",
     "\n",
     "\n",
     "\n",
     "\n",
     "## 超参数\n",
     "learning_rate = 0.1\n",
     "num_steps = 500\n",
     "batch_size = 128\n",
     "display_step = 100\n",
     "\n",
     "# 神经网络参数\n",
     "n_hidden_1 = 256 # 第一层神经元个数\n",
     "n_hidden_2 = 256 # 第二层神经元个数\n",
     "num_input = 784 # MNIST 输入数据(图像大小: 28*28)\n",
     "num_classes = 10 # MNIST 手写体数字类别 (0-9)\n",
     "\n",
     "# 输入到数据流图中的训练数据\n",
     "X = tf.placeholder(\"float\", [None, num_input])\n",
     "Y = tf.placeholder(\"float\", [None, num_classes])\n",
     "\n",
     "\n",
     "# 权重和偏置\n",
     "weights = {\n",
     "    'h1': tf.Variable(tf.random_normal([num_input, n_hidden_1])),\n",
     "    'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),\n",
     "    'out': tf.Variable(tf.random_normal([n_hidden_2, num_classes]))\n",
     "}\n",
     "biases = {\n",
     "    'b1': tf.Variable(tf.random_normal([n_hidden_1])),\n",
     "    'b2': tf.Variable(tf.random_normal([n_hidden_2])),\n",
     "    'out': tf.Variable(tf.random_normal([num_classes]))\n",
     "}\n",
     "\n",
     "# 定义神经网络\n",
     "def neural_net(x):\n",
     "    # 第一层隐藏层（256个神经元）\n",
     "    layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])\n",
     "    # 第二层隐藏层（256个神经元）\n",
     "    layer_2 = tf.add(tf.matmul(layer_1, weights['h2']), biases['b2'])\n",
     "    # 输出层\n",
     "    out_layer = tf.matmul(layer_2, weights['out']) + biases['out']\n",
     "    return out_layer\n",
     "\n",
     "# 构建模型\n",
     "logits = neural_net(X)\n",
     "\n",
     "# 定义损失函数和优化器\n",
     "loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(\n",
     "    logits=logits, labels=Y))\n",
     "optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)\n",
     "train_op = optimizer.minimize(loss_op)\n",
     "\n",
     "# 定义预测准确率\n",
     "correct_pred = tf.equal(tf.argmax(logits, 1), tf.argmax(Y, 1))\n",
     "accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))\n",
     "\n",
     "# 初始化所有变量（赋默认值）\n",
     "init = tf.global_variables_initializer()\n",
     "\n",
     "\n",
     "# 开始训练\n",
     "with tf.Session() as sess:\n",
     "\n",
     "    # 执行初始化操作\n",
     "    sess.run(init)\n",
     "\n",
     "    for step in range(1, num_steps+1):\n",
     "        batch_x, batch_y =  keras.datasets.mnist.load_data()\n",
     "        # 执行训练操作，包括前向和后向传播\n",
     "        sess.run(train_op, feed_dict={X: batch_x, Y: batch_y})\n",
     "        if step % display_step == 0 or step == 1:\n",
     "            # 计算损失值和准确率\n",
     "            loss, acc = sess.run([loss_op, accuracy], feed_dict={X: batch_x,\n",
     "                                                                 Y: batch_y})\n",
     "            print(\"Step \" + str(step) + \", Minibatch Loss= \" + \\\n",
     "                  \"{:.4f}\".format(loss) + \", Training Accuracy= \" + \\\n",
     "                  \"{:.3f}\".format(acc))\n",
     "\n",
     "    print(\"Optimization Finished!\")\n",
     "\n",
     "   "
    ]
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
